using System;

namespace ElfBinary
{
	public class SectionHeader32
	{
		public SectionHeader32 ()
		{
		}

		byte[] SectionBytes;

		public uint SectionNameIndex { get { return sh_name; }}
		public ElfSectionType SectionType { get { return (ElfSectionType)sh_type; }}
		public ElfSectionAttributeFlags SectionFlags{ get{  return (ElfSectionAttributeFlags)sh_flags; }}
		public uint Address { get { return sh_addr; }}
		public uint Offset { get { return sh_offset; }}
		public uint Size { get { return sh_size; }}
		public uint Link { get { return sh_link; }}
		public uint Info { get { return sh_info;}}
		public uint AddressAlign { get { return sh_addralign; }}
		public uint EntryItemSize { get { return sh_entsize; }}

		public void Read (System.IO.Stream s)
		{

			byte[] b = new byte[8];

			s.Read (b, 0, 4);

			sh_name = BitConverter.ToUInt32 (b, 0);

			s.Read (b, 0, 4);


			sh_type = BitConverter.ToUInt32 (b, 0);

			s.Read (b, 0, 4);

			sh_flags = BitConverter.ToUInt32 (b, 0);

			s.Read (b, 0, 4);


			sh_addr = BitConverter.ToUInt32 (b, 0);

			s.Read (b, 0, 4);


			sh_offset = BitConverter.ToUInt32 (b, 0);

			s.Read (b, 0, 4);

			sh_size = BitConverter.ToUInt32 (b, 0);

			s.Read (b, 0, 4);

			sh_link = BitConverter.ToUInt32 (b, 0);

			s.Read (b, 0, 4);


			sh_info = BitConverter.ToUInt32 (b, 0);

			s.Read (b, 0, 4);


			sh_addralign = BitConverter.ToUInt32 (b, 0);

			s.Read (b, 0, 4);


			sh_entsize = BitConverter.ToUInt32 (b, 0);

		}


		public void LoadSectionBytes(System.IO.Stream s)
		{
			s.Seek (this.Offset, System.IO.SeekOrigin.Begin);
			SectionBytes = new byte[this.Size];
			s.Read (SectionBytes, 0, (int)this.Size);

		}

		public string GetString(long offset)
		{
			if (this.SectionType != ElfSectionType.StringTable) {

				throw new Exception ("Invalid Section Type for String Extraction ! Expected: String, Object is: " + this.SectionType.ToString ());

			}

			if (SectionBytes == null) {

				throw new NullReferenceException ("You have not yet called LoadSectionBytes !");
			}


			string result = string.Empty;

			long index = (int)offset;

			while (SectionBytes [index] != 0) {

				result += (char)SectionBytes [index];
				index++;

			}

			return result;

		}


		uint	sh_name;
		uint	sh_type;
		uint	sh_flags;
		uint	sh_addr;
		uint	sh_offset;
		uint	sh_size;
		uint	sh_link;
		uint	sh_info;
		uint	sh_addralign;
		uint	sh_entsize;
	}
}

